use crate::src::src::binomial_heap::{
    binomial_heap_free, binomial_heap_insert, binomial_heap_new, binomial_heap_num_entries,
    binomial_heap_pop,
};
use crate::src::src::compare_int::int_compare;
use crate::src::struct_and_type::{
    BinomialHeap, BinomialHeapType, BinomialHeapValue, UnitTestFunction,
};
use crate::src::test::alloc_testing::alloc_test_set_limit;
use crate::src::test::framework::run_tests;

pub const BINOMIAL_HEAP_TYPE_MAX: BinomialHeapType = 1;
pub const BINOMIAL_HEAP_TYPE_MIN: BinomialHeapType = 0;
#[no_mangle]
pub static mut test_array_test_binomial_heap: [i32; 10000] = [0; 10000];
#[no_mangle]
pub extern "C" fn test_binomial_heap_new_free() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut i: i32 = 0;
    i = 0;
    while i < 10000 {
        heap = binomial_heap_new(
            BINOMIAL_HEAP_TYPE_MIN,
            Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
        );
        binomial_heap_free(heap);
        i += 1;
        i;
    }
    alloc_test_set_limit(0 as i32);
    assert!((binomial_heap_new(
        BINOMIAL_HEAP_TYPE_MIN,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
    ))
    .is_null());
}
#[no_mangle]
pub extern "C" fn test_binomial_heap_insert() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut i: i32 = 0;
    heap = binomial_heap_new(
        BINOMIAL_HEAP_TYPE_MIN,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    i = 0;
    while i < 10000 {
        (unsafe { test_array_test_binomial_heap[i as usize] = i });
        assert!(
            binomial_heap_insert(
                heap,
                (unsafe {
                    &mut *test_array_test_binomial_heap
                        .as_mut_ptr()
                        .offset(i as isize)
                }) as *mut i32 as BinomialHeapValue,
            ) != 0
        );
        i += 1;
        i;
    }
    assert!(binomial_heap_num_entries(heap) == 10000 as u32);
    alloc_test_set_limit(0 as i32);
    assert!(binomial_heap_insert(heap, &mut i as *mut i32 as BinomialHeapValue) == 0);
    binomial_heap_free(heap);
}
#[no_mangle]
pub extern "C" fn test_min_heap_test_binomial_heap() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut val: *mut i32 = 0 as *mut i32;
    let mut i: i32 = 0;
    heap = binomial_heap_new(
        BINOMIAL_HEAP_TYPE_MIN,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    i = 0;
    while i < 10000 {
        (unsafe { test_array_test_binomial_heap[i as usize] = i });
        assert!(
            binomial_heap_insert(
                heap,
                (unsafe {
                    &mut *test_array_test_binomial_heap
                        .as_mut_ptr()
                        .offset(i as isize)
                }) as *mut i32 as BinomialHeapValue,
            ) != 0
        );
        i += 1;
        i;
    }
    i = -(1 as i32);
    while binomial_heap_num_entries(heap) > 0 as u32 {
        val = binomial_heap_pop(heap) as *mut i32;
        assert!((unsafe { *val }) == i + 1);
        i = unsafe { *val };
    }
    val = binomial_heap_pop(heap) as *mut i32;
    assert!(val.is_null());
    binomial_heap_free(heap);
}
#[no_mangle]
pub extern "C" fn test_max_heap_test_binomial_heap() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut val: *mut i32 = 0 as *mut i32;
    let mut i: i32 = 0;
    heap = binomial_heap_new(
        BINOMIAL_HEAP_TYPE_MAX,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    i = 0;
    while i < 10000 {
        (unsafe { test_array_test_binomial_heap[i as usize] = i });
        assert!(
            binomial_heap_insert(
                heap,
                (unsafe {
                    &mut *test_array_test_binomial_heap
                        .as_mut_ptr()
                        .offset(i as isize)
                }) as *mut i32 as BinomialHeapValue,
            ) != 0
        );
        i += 1;
        i;
    }
    i = 10000;
    while binomial_heap_num_entries(heap) > 0 as u32 {
        val = binomial_heap_pop(heap) as *mut i32;
        assert!((unsafe { *val }) == i - 1);
        i = unsafe { *val };
    }
    val = binomial_heap_pop(heap) as *mut i32;
    assert!(val.is_null());
    binomial_heap_free(heap);
}
extern "C" fn generate_heap() -> *mut BinomialHeap {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut i: i32 = 0;
    heap = binomial_heap_new(
        BINOMIAL_HEAP_TYPE_MIN,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    i = 0;
    while i < 10000 {
        (unsafe { test_array_test_binomial_heap[i as usize] = i });
        if i != 10000 / 2 {
            assert!(
                binomial_heap_insert(
                    heap,
                    (unsafe {
                        &mut *test_array_test_binomial_heap
                            .as_mut_ptr()
                            .offset(i as isize)
                    }) as *mut i32 as BinomialHeapValue,
                ) != 0
            );
        }
        i += 1;
        i;
    }
    return heap;
}
extern "C" fn verify_heap(mut heap: *mut BinomialHeap) {
    let mut num_vals: u32 = 0;
    let mut val: *mut i32 = 0 as *mut i32;
    let mut i: i32 = 0;
    num_vals = binomial_heap_num_entries(heap);
    assert!(num_vals == (10000 as i32 - 1) as u32);
    i = 0;
    while i < 10000 {
        if !(i == 10000 / 2) {
            val = binomial_heap_pop(heap) as *mut i32;
            assert!((unsafe { *val }) == i);
            num_vals = num_vals.wrapping_sub(1);
            num_vals;
            assert!(binomial_heap_num_entries(heap) == num_vals);
        }
        i += 1;
        i;
    }
}
extern "C" fn test_insert_out_of_memory() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut i: i32 = 0;
    i = 0;
    while i < 6 {
        heap = generate_heap();
        alloc_test_set_limit(i);
        (unsafe {
            test_array_test_binomial_heap[(10000 as i32 / 2) as usize] = 10000 / 2
        });
        assert!(
            binomial_heap_insert(
                heap,
                (unsafe {
                    &mut *test_array_test_binomial_heap
                        .as_mut_ptr()
                        .offset((10000 as i32 / 2) as isize)
                }) as *mut i32 as BinomialHeapValue,
            ) == 0
        );
        alloc_test_set_limit(-(1 as i32));
        verify_heap(heap);
        binomial_heap_free(heap);
        i += 1;
        i;
    }
}
#[no_mangle]
pub extern "C" fn test_pop_out_of_memory() {
    let mut heap: *mut BinomialHeap = 0 as *mut BinomialHeap;
    let mut i: i32 = 0;
    i = 0;
    while i < 6 {
        heap = generate_heap();
        alloc_test_set_limit(i);
        assert!((binomial_heap_pop(heap)).is_null());
        alloc_test_set_limit(-(1 as i32));
        binomial_heap_free(heap);
        i += 1;
        i;
    }
}
static mut tests_test_binomial_heap: [UnitTestFunction; 7] = {
    [
        Some(test_binomial_heap_new_free as unsafe extern "C" fn() -> ()),
        Some(test_binomial_heap_insert as unsafe extern "C" fn() -> ()),
        Some(test_min_heap_test_binomial_heap as unsafe extern "C" fn() -> ()),
        Some(test_max_heap_test_binomial_heap as unsafe extern "C" fn() -> ()),
        Some(test_insert_out_of_memory as unsafe extern "C" fn() -> ()),
        Some(test_pop_out_of_memory as unsafe extern "C" fn() -> ()),
        None,
    ]
};
fn main_0_test_binomial_heap(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    run_tests(unsafe { tests_test_binomial_heap.as_mut_ptr() });
    return 0;
}
pub fn main_test_binomial_heap() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(main_0_test_binomial_heap(
            (args.len() - 1) as i32,
            args.as_mut_ptr() as *mut *mut i8,
        ) as i32)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn entry_for_test_binomial_heap_new_free() {
        test_binomial_heap_new_free();
    }
    #[test]
    fn entry_for_test_binomial_heap_insert() {
        test_binomial_heap_insert();
    }
    #[test]
    fn entry_for_test_min_heap_test_binomial_heap() {
        test_min_heap_test_binomial_heap();
    }
    #[test]
    fn entry_for_test_max_heap_test_binomial_heap() {
        test_max_heap_test_binomial_heap();
    }
    #[test]
    fn entry_for_test_insert_out_of_memory() {
        test_insert_out_of_memory();
    }
    #[test]
    fn entry_for_test_pop_out_of_memory() {
        test_pop_out_of_memory();
    }
}